package com.jwater.core.manager.proxy.collect;

import com.jwater.core.manager.common.conf.CoreConfParse;
import com.jwater.core.manager.common.model.AlarmInfo;
import com.jwater.core.manager.common.model.SystemInfo;
import com.jwater.core.manager.proxy.ProxyNode;
import com.jwater.core.metrics.FileSystemSpace;
import com.jwater.core.metrics.SystemMetric;
import com.jwater.launch.HomePath;
import jwater.org.springframework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @description:
 * @author: jnner
 * @createDate: 2021/3/21
 * @version: 1.0
 */
public class SystemCollect implements Runnable {
    protected static Logger logger = LoggerFactory.getLogger(SystemCollect.class);
    private Thread thread;
    private String path;
    private ProxyNode proxyNode;
    private String host;
    private double diskLimit;
    private double memLimit;
    private double cpuLimit;

    public SystemCollect(ProxyNode proxyNode, String host) {
        this.proxyNode = proxyNode;
        this.host = host;
    }

    public void start() {
        String homePath = HomePath.getHomePath();
        for (Map.Entry<String, FileSystemSpace> en : SystemMetric.getFileSystemSpace().entrySet()) {
            if (homePath.startsWith(en.getKey().replace("\\", "/"))) {
                path = en.getKey();
                break;
            }
        }
        CoreConfParse coreConfParse = new CoreConfParse();
        coreConfParse.parse();
        diskLimit = coreConfParse.getDiskLimit();
        memLimit = coreConfParse.getMemLimit();
        cpuLimit = coreConfParse.getCpuLimit();
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            try {
                collect();
            } catch (Exception e) {
                logger.error(e.toString(), e);
            }
            synchronized (this) {
                try {
                    this.wait(30000);
                } catch (InterruptedException e) {
                    logger.error(e.toString(), e);
                }
            }
        }
    }

    private void collect() {
        SystemInfo systemInfo = new SystemInfo();
        systemInfo.setSystemMemory(SystemMetric.getSystemMemory());
        systemInfo.setCpuUsage(SystemMetric.getCpuUsage());
        systemInfo.setAllFileSystemSpace(SystemMetric.getFileSystemSpace());
        FileSystemSpace fileSystemSpace = new FileSystemSpace(0d, 0d, 0d);
        if (!StringUtils.isEmpty(path)) {
            fileSystemSpace = systemInfo.getAllFileSystemSpace().get(path);
            systemInfo.setPath(path);
        }
        //systemInfo.setAllCpuUsage(SystemMetric.getAllCpuUsage());
        //systemInfo.setUsedPort(SystemMetric.getUsedPort());
        //systemInfo.setDiskRate(SystemMetric.getDiskRate());
        //systemInfo.setNetRate(SystemMetric.getNetRate());
        systemInfo.setCurrTime(System.currentTimeMillis());
        Map<String, Double> mems = systemInfo.getSystemMemory();
        logger.info("total-memory:{},free-memory:{},cached:{},cpu:{},disk-path:{},totalSpace:{},freeSpace:{}"
                , mems.get("total"), mems.get("free"), mems.get("cached"), systemInfo.getCpuUsage(), path,
                fileSystemSpace.getTotalSpace(), fileSystemSpace.getFreeSpace()
        );
        this.proxyNode.reportSystemInfo(systemInfo);
        checkAlarm(systemInfo);
    }

    private void checkAlarm(SystemInfo systemInfo) {
        checkDisk(systemInfo);
        checkMemory(systemInfo);
        checkCpu(systemInfo);
    }

    private void checkDisk(SystemInfo systemInfo) {
        if (StringUtils.isEmpty(path)) {
            return;
        }
        FileSystemSpace fileSystemSpace = systemInfo.getAllFileSystemSpace().get(path);
        if (fileSystemSpace == null) {
            return;
        }
        if (fileSystemSpace.getFreeSpace() < diskLimit) {
            double free = (int) fileSystemSpace.getFreeSpace() * 100 * 1.0 / 100;
            String msg = "磁盘挂载点" + path + "剩余大小" + free + "G小于" + diskLimit + "G";
            AlarmInfo alarmInfo = new AlarmInfo();
            alarmInfo.setMsg(msg);
            alarmInfo.setType(host + "-disk");
            alarmInfo.setAlarmTime(System.currentTimeMillis());
            proxyNode.reportAlarmInfo(alarmInfo);
        }
    }

    private void checkMemory(SystemInfo systemInfo) {
        double free = systemInfo.getSystemMemory().get("free");
        if (free < memLimit) {
            free = (int) free * 100 * 1.0 / 100;
            String msg = "内存剩余" + free + "M小于" + memLimit + "M";
            AlarmInfo alarmInfo = new AlarmInfo();
            alarmInfo.setMsg(msg);
            alarmInfo.setType(host + "-memory");
            alarmInfo.setAlarmTime(System.currentTimeMillis());
            proxyNode.reportAlarmInfo(alarmInfo);
        }
    }

    private void checkCpu(SystemInfo systemInfo) {
        double cpuUsage = systemInfo.getCpuUsage();
        if (cpuUsage > cpuLimit) {
            cpuUsage = (int) cpuUsage * 100 * 1.0 / 100;
            String msg = "CPU使用率" + cpuUsage + "大于" + cpuLimit;
            AlarmInfo alarmInfo = new AlarmInfo();
            alarmInfo.setMsg(msg);
            alarmInfo.setType(host + "-cpu");
            alarmInfo.setAlarmTime(System.currentTimeMillis());
            proxyNode.reportAlarmInfo(alarmInfo);
        }
    }
}
